package cn.virens.common.mybatis.mapper.example.mapper;

import cn.virens.common.mybatis.mapper.example.Example;
import io.mybatis.provider.Caching;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

public interface ExampleMapper<T> {

    /**
     * 根据 Example 删除
     *
     * @param example 条件
     * @return 大于等于1成功，0失败
     */
    @Lang(Caching.class)
    @DeleteProvider(type = ExampleProvider.class, method = "deleteByExample")
    int deleteByExample(@Param("example") Example example);

    /**
     * 根据 Example 条件批量更新实体信息
     *
     * @param entity  实体类
     * @param example 条件
     * @return 大于等于1成功，0失败
     */
    @Lang(Caching.class)
    @UpdateProvider(type = ExampleProvider.class, method = "updateByExample")
    int updateByExample(@Param("entity") T entity, @Param("example") Example example);

    /**
     * 根据 Example 条件批量更新实体不为空的字段
     *
     * @param entity  实体类
     * @param example 条件
     * @return 大于等于1成功，0失败
     */
    @Lang(Caching.class)
    @UpdateProvider(type = ExampleProvider.class, method = "updateByExampleSelective")
    int updateByExampleSelective(@Param("entity") T entity, @Param("example") Example example);

    /**
     * 根据 Example 条件批量查询
     *
     * @param example 条件
     * @return 实体列表
     */
    @Lang(Caching.class)
    @SuppressWarnings("all")
    @SelectProvider(type = ExampleProvider.class, method = "selectByExample")
    List<T> selectByExample(@Param("example") Example example);

    /**
     * 根据 Example 条件批量查询
     *
     * @param example 条件
     * @return 实体列表
     */
    @Lang(Caching.class)
    @ResultType(value = Map.class)
    @SelectProvider(type = ExampleProvider.class, method = "selectByExample")
    List<Map<String, Object>> selectMapByExample(@Param("example") Example example);

    /**
     * 根据 Example 条件批量查询
     *
     * @param example 条件
     * @return 实体列表
     */
    @Lang(Caching.class)
    @SelectProvider(type = ExampleProvider.class, method = "selectCountByExample")
    long selectCountByExample(@Param("example") Example example);

    /**
     * 根据 Example 条件单条查询
     *
     * @param example 条件
     * @return 实体列表
     */
    default T selectOneByExample(@Param("example") Example example) {
        if (example != null) example.setLimitByClause(1);

        List<T> list = selectByExample(example);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 根据 Example 条件单条查询
     *
     * @param example 条件
     * @return 实体列表
     */
    default Map<String, Object> selectOneMapByExample(@Param("example") Example example) {
        if (example != null) example.setLimitByClause(1);

        List<Map<String, Object>> list = selectMapByExample(example);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        } else {
            return null;
        }
    }
}
